#! /usr/bin/env python

import clr
import json
import platform
import os

# List for hardware types and sensor types that our DLL can open
OHM_hwtypes = ['Mainboard', 'SuperIO', 'CPU', 'RAM',
               'GpuNvidia', 'GpuAti', 'TBalancer', 'Heatmaster', 'HDD']
OHM_sensortypes = [
    'Voltage', 'Clock', 'Temperature', 'Load', 'Fan', 'Flow', 'Control', 'Level', 'Factor', 'Power', 'Data', 'SmallData'
]


def init_OHM():
    """
    它添加对 OpenHardwareMonitorLib.dll 文件的引用，从 OpenHardwareMonitor 模块导入 Hardware 类，创建一个 Computer
    对象，启用主板、CPU、RAM、GPU 和 HDD 的传感器，然后打开计算机对象
    :return: 硬件对象列表。
    """
    clr.AddReference(os.path.abspath(os.path.dirname(
        __file__)) + R'\OpenHardwareMonitorLib.dll')
    from OpenHardwareMonitor import Hardware
    hw = Hardware.Computer()
    hw.MainboardEnabled, hw.CPUEnabled, hw.RAMEnabled, hw.GPUEnabled, hw.HDDEnabled = True, True, True, True, True
    hw.Open()
    return hw


def fetch_data(handle):
    """
    它接受 OpenHardwareMonitor 对象的句柄，并返回一个字典列表，每个字典都包含传感器的名称、值和单位
    
    :param handle: OpenHardwareMonitor.Hardware.Computer 对象的句柄
    :return: 字典列表。
    """
    out = []
    for i in handle.Hardware:
        i.Update()
        for sensor in i.Sensors:
            thing = parse_sensor(sensor)
            if thing is not None:
                out.append(thing)
        for j in i.SubHardware:
            j.Update()
            for subsensor in j.Sensors:
                thing = parse_sensor(subsensor)
                out.append(thing)
    return out


def parse_sensor(snsr):
    """
    如果传感器值不是无，并且传感器类型是温度，则返回包含硬件类型、硬件名称、传感器名称和传感器读数的字典
    
    :param snsr: 传感器对象
    :return: 具有以下键的字典：
    类型：传感器连接到的硬件类型。
    名称：传感器所连接的硬件的名称。
    传感器：传感器的名称。
    读数：传感器的值。
    """
    if snsr.Value is not None:
        if snsr.SensorType == OHM_sensortypes.index('Temperature'):
            HwType = OHM_hwtypes[snsr.Hardware.HardwareType]
            return {"Type": HwType, "Name": snsr.Hardware.Name, "Sensor": snsr.Name, "Reading": u'%s\xb0C' % snsr.Value}


def main():
    """
    它返回 js 变量。
    :return: 正在返回 js 变量。
    """
    return json.dumps({platform.node(): fetch_data(init_OHM())}, indent=1, sort_keys=True, ensure_ascii=False)


if __name__ == "__main__":
    print('Hardware Monitor:')
    print(main())
